package com.grj.parking.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.grj.parking.aaa.ElasticsearchService;
import com.grj.parking.domain.ParkingLot;
import com.grj.parking.service.ParkingLotService;
import com.grj.parking.mapper.ParkingLotMapper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* @author ganru
* @description 针对表【parking_lot(停车场信息表（含经纬度）)】的数据库操作Service实现
* @createDate 2025-09-02 03:28:07
*/
@Service
public class ParkingLotServiceImpl extends ServiceImpl<ParkingLotMapper, ParkingLot>
    implements ParkingLotService{


    @Autowired
    private ElasticsearchService elasticsearchService;

    @Autowired
    private ParkingLotMapper parkingLotMapper;

    @Autowired
    private RestHighLevelClient elasticsearchClient;

    // 索引名称
    private static final String INDEX_NAME = "parking_lot";

    /**
     * 全量同步数据库数据到ES
     */
    public boolean fullSyncToEs() throws Exception {
        // 先创建索引（如果不存在）
//        try {
//            elasticsearchService.createIndex();
//        } catch (Exception e) {
//            // 索引已存在时会抛出异常，这里忽略
//            System.out.println("索引可能已存在: " + e.getMessage());
//        }

        List<ParkingLot> parkingLots = parkingLotMapper.selectList( null);
        if (parkingLots.isEmpty()) {
            return false;
        }

        boolean success = elasticsearchService.bulkSync(parkingLots);


        return true;
    }



    /**
     * 搜索附近的停车场
     */
    public List<ParkingLot> searchNearby(double latitude, double longitude, double distance, int pageNum, int pageSize) throws IOException {
        return elasticsearchService.searchNearby(latitude, longitude, distance, pageNum, pageSize);
    }

    /**
     * 对停车场名称进行模糊查询
     * @param lotName 模糊查询关键词
     * @param pageable 分页参数
     * @return 分页结果
     */
    public Page<ParkingLot> fuzzySearchByLotName(String lotName, Pageable pageable) {
        try {
            // 创建搜索请求
            SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            // 构建模糊查询条件
            if (lotName != null && !lotName.trim().isEmpty()) {
                // 使用fuzzy query实现模糊匹配，支持拼写错误（最多2个字符差异）
                searchSourceBuilder.query(QueryBuilders.fuzzyQuery("lotName", lotName)
                        .fuzziness(Fuzziness.AUTO)  // 自动判断模糊程度
                        .prefixLength(1));  // 前缀至少匹配1个字符
            } else {
                // 如果没有传入关键词，查询所有
                searchSourceBuilder.query(QueryBuilders.matchAllQuery());
            }

            // 高亮显示匹配的关键词
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            HighlightBuilder.Field highlightField = new HighlightBuilder.Field("lotName");
            highlightField.preTags("<em>");  // 高亮前缀
            highlightField.postTags("</em>");  // 高亮后缀
            highlightBuilder.field(highlightField);
            searchSourceBuilder.highlighter(highlightBuilder);

            // 设置分页
            searchSourceBuilder.from((int) pageable.getOffset());
            searchSourceBuilder.size(pageable.getPageSize());

            // 执行搜索
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
            // 处理搜索结果
            List<ParkingLot> parkingLots = new ArrayList<>();
            for (SearchHit hit : searchResponse.getHits().getHits()) {
                // 将JSON转换为实体类
                ParkingLot parkingLot = JSON.parseObject(hit.getSourceAsString(), ParkingLot.class);


                // 处理高亮结果（如果有）
                if (hit.getHighlightFields() != null && !hit.getHighlightFields().isEmpty()) {
                    String highlightedName = hit.getHighlightFields().get("lotName").getFragments()[0].toString();
                    parkingLot.setLotName(highlightedName);
                }

                parkingLots.add(parkingLot);
            }

            // 构建分页结果
            Page<ParkingLot> page = new Page<>();
            page.setTotal(searchResponse.getHits().getTotalHits().value);
            page.setRecords(parkingLots);
            return page;

        } catch (IOException e) {
            throw new RuntimeException("模糊查询停车场名称失败", e);
        }
    }
}




